#include "backend.h"

#if defined(Q_OS_WIN)
#include <Windows.h>
#elif defined(Q_OS_LINUX)
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <crypt.h>
#include <fstream>
#include <sstream>
#endif
#include <QDebug>

Backend::Backend(QObject *parent) : QObject(parent)
{

}

bool Backend::verifyCredentials(const QString& username, const QString& password)
{
#if defined(Q_OS_WIN)
    HANDLE tokenHandle;
    BOOL result;
    // 将QString转换为宽字符字符串
    std::wstring usernameW = username.toStdWString();
    std::wstring passwordW = password.toStdWString();
    result = LogonUserW(usernameW.c_str(),
                        NULL,
                        passwordW.c_str(),
                        LOGON32_LOGON_INTERACTIVE,
                        LOGON32_PROVIDER_DEFAULT,
                        &tokenHandle);
    if (result) {
        CloseHandle(tokenHandle);
        return true;
    }
    return false;
#elif defined(Q_OS_LINUX)
    // 打开 /etc/shadow 文件
    std::ifstream shadow("/etc/shadow");
    if (!shadow.is_open()) {
        qDebug() << "无法打开 /etc/shadow 文件";
        return false;
    }

    std::string line;
    std::string user;
    while (std::getline(shadow, line)) {
        std::istringstream iss(line);
        std::getline(iss, user, ':');
        if (user == username.toStdString()) {
            std::string shadowPassword;
            std::getline(iss, shadowPassword, ':'); // 加密的密码
            std::string salt;
            std::getline(iss, salt, '$'); // 盐值
            salt = shadowPassword.substr(0, shadowPassword.find('$', 3)); // 提取盐值部分

            char *encryptedPassword = crypt(password.toStdString().c_str(), salt.c_str());
            if (encryptedPassword != nullptr && shadowPassword == encryptedPassword) {
                return true;
            }
            break;
        }
    }
    return false;
#else
    return false;
#endif
}

void Backend::setHostInfo(QString host, QString user)
{
    _host  = host;
    _user  = user;
    emit hostChanged(_host);
    emit userChanged(_user);
    qDebug() << "host: " << host << "user: " << user;
}
